from typing import TypeVar, Iterator, Tuple
import typing


T = TypeVar("T", int, float, complex)
Vector = Iterator[Tuple[T, T]]


def inproduct(v: Vector[T]) -> T:
    return sum(x * y for x, y in v)


def dilate(v: Vector[T], scale: T) -> Vector[T]:
    return ((x * scale, y*scale) for x, y in v)


@typing.overload
def get(resp: int) -> int:
    return resp


@typing.overload
def get(resp: str) -> str:
    return resp


def get(resp) -> None:
    print("resp")

# a = get("yonghu")
# print(a)
from typing import Dict, Tuple, Sequence


connection_options = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, connection_options]

def sub(a: Server) -> Server:
    return a

a = (("127.0.0.1", 3306), {"a": "b"})
b = sub(a)
print(b)


def add(a: Address) -> Address:
    return a




# def put(a: connection_options) -> connection_options:
#     return a
#
# a = {"a": " "}
# b = put(a)
# print(b)


"""
期望使用特定的签名的回调函数的框架可以使用来提示类型。 
    Callable[[Arg1Type, Arg2Type], ReturnType]
"""
from typing import Callable

def feeder(get_next_item: Callable[[], str]) -> None:
    pass

def async_query(on_success: Callable[[int], None],
                on_error: Callable[[int, Exception], None]) -> None:
    pass


"""
通过文字省略号代替类型提示中的参数的列表，因此抽象基类已经扩展为支持预定，
以表示容器元素的预期类型。
"""

# from typing import Mapping, Sequence
#
# def notify__by_email(employees: Sequence[Employee],
#                      overides: Mapping[str, str]) -> None:
#     pass
#
from typing import TypeVar, Generic
from logging import Logger

T = TypeVar("T")

class LoggerdVar(Generic[T]):
    def __init__(self, value: T, name: str) -> None:
        self.name = name
        self.logger = Logger
        self.value = value

    def set(self, new: T) -> None:
        self.logger("Set" + repr(self.value))
        self.value = new

    def get(self)-> T:
        self.logger("Get", repr(self.value))
        return self.value

    def log(self, message: str) -> None:
        self.logger.info("%s: %s", self.name, message)


def zero_all_vars(vars: typing.Iterable[LoggerdVar[int]]) -> None:
    for var in vars:
        var.set(0)


list1 = [LoggerdVar(1, "int"), LoggerdVar("2", "str"),
         LoggerdVar(1.05, "float")]

# for i in list1:
#     print(i.value)

X = TypeVar("X")
Y = TypeVar("Y")

def lookup_name(mapping: typing.Mapping[X, Y], key: X, default: Y) -> Y:
    try:
        return mapping[key]
    except KeyError:
        return default

a = lookup_name({"date": "2019-09-21"}, "date", None)
print(a)































